<template>
	<div class="webpack-plugin-test-event">
		<h1>{{ message }}</h1>
		<p>不同于loader 被用于转换某些类型的模块，plugin可适用范围更广泛，例如打包优化、环境变量注入</p>
		<p>自己构建一个plugin也很简单，它本质是一个构造函数：</p>
		<code>
			<pre>
                function test() {}
                test.prototype.apply = function (complier){
                    // 制定一个挂到webpack勾子上的事件
                    compiler.plugin('emit', function(compilation , callback) {
                        // 干你想干的事
                        callback();
                    });
                }

                // 或者
                class test {
                    constructor (params) {}
                    apply(compiler) {
                        // 制定一个挂到webpack勾子上的事件
                        compiler.hooks.emit.tap('FileListPlugin', (compilation, callback) => {
                            // 干你想干的事
                            callback()
                        })
                    }
                }

                module.exports = test;
			</pre>
		</code>
        <h3>compiler和compilation</h3>
        <ul>
            <li>compiler对象包涵了Webpack环境所有的的配置信息，这个对象在Webpack启动时候被构建，并配置上所有的设置选项包括 options，loaders，plugins。当启用一个插件到Webpack环境的时候，这个插件就会接受一个指向compiler的参数。运用这个参数来获取到Webpack环境,继承了tapable</li>
            <li>compilation代表了一个单一构建版本的物料。在webpack中间件运行时，每当一个文件发生改变时就会产生一个新的compilation从而产生一个新的变异后的物料集合。compilation列出了很多关于当前模块资源的信息，编译后的资源信息，改动过的文件，以及监听过的依赖。compilation也提供了插件需要自定义功能的回调点。</li>
            <li><a href="https://github.com/webpack/webpack/blob/master/lib/Compilation.js">Compilation 源文件</a></li>
            <li><a href="https://github.com/webpack/webpack/blob/master/lib/Compiler.js">Compiler 源文件</a></li>
        </ul>
        <h3>一个简单的获取项目代码目录输出成object形式</h3>
        <code>
            <pre>
                const fs = require('fs');
                const UglifyJS = require("uglify-js");
                class FileListPlugin {
                    constructor (params) {
                        this.path = params.path;
                    }
                    apply(compiler) {
                        let _this = this;
                        compiler.hooks.emit.tapAsync('FileListPlugin', (compilation, callback) => {
                            let pre = compiler.context.split(/\/|\\/);
                            let base = pre[pre.length - 1];
                            let depFile = [];
                            let reg = `^(.*${base})`;
                            depFile = Array.from(compilation.fileDependencies).filter(item => !item.includes('node_modules')).map(item => {
                                return item.replace(new RegExp(reg, 'g'), base).split(/\/|\\/);
                            });

                            let fileObjTree = {};
                            //转换成树形
                            function toTree(arr) {
                                function init (obj, key, file) {
                                    if (!obj[key]) {
                                        obj[key] = {}
                                    }

                                    return obj[key];
                                }
                                for (let i = 0; i &lt; arr.length; i++){
                                    let inner = fileObjTree;
                                    for (let j = 0; j &lt; arr[i].length; j++){
                                        inner = init(inner, arr[i][j]);
                                    }
                                }
                            }

                            toTree(depFile);
                            fs.writeFile('dist/abc.json', JSON.stringify(fileObjTree, null, 4), (err) => {
                                if (err) throw err;
                                console.log('文件已被保存');
                            });
                            callback();
                        });
                    }
                }
                    
                module.exports = FileListPlugin;

            </pre>
        </code>
		<p class="page-end">The End</p>
	</div>
</template>

<script lang="ts">
    import Vue from 'vue';
    import Component from 'vue-class-component';
    @Component({
        // 所有的组件选项都可以放在这里
    })
    export default class plugin extends Vue {
        // data 在这
        message: string = 'webpack自定义plugin'

        created () {
        }
    }
</script>
<style lang="scss">
.webpack-plugin-test-event{
}
</style>